// #include<iostream>
// #include<vector>
// #include<map>
// #include<cstring>
// #include<string>
// using namespace std;

#if 0
void test01()
{
    // 数组
    int arr[]{ 1,2,3,4 };

    // 内置类型
    int a{1};      // 相当于 int a = 1;
    double b{3.14};
    char c{'c'};

    // STL容器
    vector<int> v{ 1,2,3,4,5 };
    map<int,int> m{ {1,1}, {2,2}, {3,3} };
    string s{"xxxxx"};

    // int a = { 3.14 }; // 丢失小数部分
    // size_t sz{ -1 }; // 丢失符号
}

class A
{
public:
    // explicit A(int a)
    // {
    //     cout << "A(int a)" << endl;
    // }
    A(int a, int b)
    {
        cout << "A(int a, int b)" << endl;
    }
    A(initializer_list<int> il)
    {
        cout << "A(initializer_list<int> il)" << endl;
    }
    // A(int a, char c)
    // {
    //     cout << "A(int a, char c)" << endl;
    // }
};

void test02()
{
    A a(1, 1);
    A a1{1, 1};     // 直接列表初始化。相当于A a1(1, 1);
    A a2 = {1, 1};  // 拷贝列表初始化。编译报错，无法调用explicit修饰的构造函数
    // A a1{1};         // 调用A(int a)
    // A a2 = {1, 2};      // 调用A(int a, int b)
    // A a3 = {1, 'c'};    // 调用A(int a, char c)

    // int a1(1);      // 直接初始化
    // int a2{1};      // 直接列表初始化。相当于 int a2(1)，但是会额外对窄化转换进行检查。例如int a(1.1);可编译通过，而int a{1.1};会编译报错
    // int a3 = {1};   // 拷贝列表初始化。相当于 int a3 = int{1}; 编译器会先用花括号内的内容创建一个临时的int对象，然后再将这个临时对象的值拷贝给a3
}

void test03()
{
    // auto a = 1;     // auto推导为int
    // auto b = 3.14;  // auto推导为double
    // vector<int> v = {1,2,3};
    // auto v1 = v;    // auto推导为vector<int>

    const int a = 10;
    auto a1 = a;    // 值推导。auto推导为int，而非const int
    a1 = 20;

    // auto& a2 = a;   // 引用推导。auto推导为const int
    // a2 = 20;    // 编译报错

    // auto* p = &a;   // 指针推导。auto推导为const int
    // *p = 20;    // 编译报错
}

void test04()
{
    int a = 1;
    double b = 2.1;
    decltype(a) x1;      // x1为int类型
    decltype(a * b) x2;  // x2为double类型
    decltype(&b) p;      // p为double*类型
}

void test05()
{
    // int a = 1;
    // int* p = &a;
    // *p = 20;
    // const int b = a;
    // int arr[] = { 1,2,3 };
    // arr[1] = 10;

    // // a, p, *p, b, arr, arr[1]都是左值

    // int& r1 = a;
    // int*& r2 = p;
    // const int& r3 = b;

    int a = 10, b = 20;

    // 以下均为右值
    10;         // 字面常量
    3.14;       // 字面常量
    a + b;      // 表达式返回值
    abs(a);     // 函数返回值
    string("hello");    // 匿名对象

    int&& rr1 = 10;
    printf("%p", &rr1); // 可以取到rr1的地址，rr1是左值
    rr1 = 20;   // 可以修改rr1
    // double&& rr2 = 3.14;
    // int&& rr3 = a + b;
    // int&& rr4 = abs(a);
    // string&& rr5 = string("hello");
}

void test06()
{
    int a = 1, b = 2;

    // const左值引用可以引用右值
    const int& r1 = 10;     
    const int& r2 = a + b;
    const string& r3 = string("1111");

    // 右值引用可以引用move后的左值
    int&& rr1 = move(a);
    string s("111");
    string&& rr2 = move(s);
    string&& rr3 = (string&&)s;
}

class B
{
public:
    int _b;
    B(int b = 1) { cout << "B(int b = 1)" << endl; }
    ~B() { cout << "~B()" << endl; }
};

void test07()
{
    B&& r = B(2);	// 右值引用引用右值，会接管其资源，也会延长其声明周期
    cout << "--------" << endl;
    r._b = 20;  // 可以修改
}

void func(const int& x)
{
    cout << "void func(const int& x)" << endl;
}
void func(int&& x)
{
    cout << "void func(int&& x)" << endl;
}

void test08()
{
    func(10);
}

int main()
{
    test08();
    return 0;
}

#endif

// class A
// {
// 	int* _arr = nullptr;
// 	int _size = 0;
// public:
// 	A(int n = 10)
// 		:_arr(new int[n])
// 		,_size(n)
// 	{ 
// 		cout << "A(int n = 10)" << endl;
// 	}

// 	// A(A&& a)
//     // {
//     //     std::swap(_arr, a._arr);
//     //     std::swap(_size, a._size);
//     //     cout << "A(A&& a)" << endl;
//     // }

// 	A(const A& a)
// 		:_arr(new int[a._size])
// 		, _size(a._size)
// 	{
// 		cout << "A(const A& a)" << endl;
// 		memcpy(_arr, a._arr, sizeof(int) * _size);
// 	}

//     A& operator= (const A& a)
//     {
// 		cout << "A& operator= (const A& a)" << endl;
//         if(this == &a) return *this;
//         delete[] _arr;
//         _arr = new int[a._size];
//         _size = a._size;
//         memcpy(_arr, a._arr, sizeof(int) * _size);
//         return *this;
//     }

//     // A& operator= (A&& a)
//     // {
// 	// 	cout << "A& operator= (A&& a)" << endl;
//     //     std::swap(_arr, a._arr);
//     //     std::swap(_size, a._size);
//     //     return *this;
//     // }

// 	~A()
// 	{
// 		delete[] _arr;
// 		_arr = nullptr;
// 		_size = 0;
// 		cout << "~A()" << endl;
// 	}
// };

// class B
// {
//     A _a;
//     int _b;
// };

// int main()
// {
//     B b1;
//     B b2(move(b1)); 
//     return 0;
// }

// A func()	
// {
// 	A a(1000);
// 	return a;
// }

// void _func(const A& a)
// {
//     cout << "void _func(const A& a)" << endl;
// }
// void _func(A&& a)
// {
//     cout << "void _func(A&& a)" << endl;
// }

// void func(A&& a)
// {
//     cout << "void func(A&& a)" << endl;
//     _func(a);
// }

// int main()
// {
//     // A a1(100);
//     // a1 = func();

//     // A a1 = 100;
//     // func(A(100));
// 	return 0;
// }

// void F(int& x) { cout << "左值引用" << endl; }
// void F(const int& x) { cout << "const左值引用" << endl; }
// void F(int&& x) { cout << "右值引用" << endl; }
// void F(const int&& x) { cout << "const右值引用" << endl; }

// template<class T>
// void func(T&& t)  // 模板中的 T&& 是万能引用
// {
//     F(forward<T>(x));
// }

// // void func(int&& t)
// // {
// //     cout << "void func(int&& t)" << endl;
// // }

// int main()
// {
//     int a = 10;
//     func(a);        // 左值
//     func(move(a));  // 右值

//     const int b = 20;
//     func(b);        // const左值
//     func(move(b));  // const右值
//     return 0;
// }

/*
template<class T, class ...Args>
void Print(T&& x, Args&&... args)
{
    if(sizeof...(args) == 0) return;    // 不能这样写，因为是编译时推导
    cout << typeid(x).name() << ' ';
    Print(args...);
}*/


// int main()
// {
//     // 左值引用给右值取别名
//     int& r1 = 10;       
//     int& r2 = abs(-1);

//     int a = 10;
//     string s("xxxx");

//     // 右值引用给左值取别名
//     int&& rr1 = a;
//     string&& rr2 = s;
//     return 0;
// }

// void Print()
// {
//     cout << endl;
// }

// template<class T, class ...Args>
// void Print(T&& x, Args&&... args)
// {
//     cout << typeid(x).name() << ' ';
//     Print(args...);
// }

// template<class ...Args>     // Args是一个模板参数包，表示可以接收任意数量的模板参数。在编译时推导参数
// void func(Args&&... x)
// {
//     cout << sizeof...(x) << endl;   // 输出x有几个参数
//     // Print(x...);    // 传递时需要这样写
// }

// int main()
// {
//     func();              // 输出 0
//     func(1);             // 输出 1
//     func(1, 'a');        // 输出 2
//     func(1, 3.14, "xxx");// 输出 3
//     return 0;
// }

// void Print()
// {
//     cout << endl;
// }

// template<class T, class ...Args>
// void Print(T x, Args... args)
// {
//     cout << x << ' ';
//     Print(args...);
// }

// template<class ...Args>     // Args是一个模板参数包，表示可以接收任意数量、任意类型的模板参数。在编译时推导
// void func(Args&&... x)
// {
//     Print(x...);    // x是个参数包，传参时需要在x后面加上...
// }

/*
void func(int x, double y, const char* z)
{
	Print(x, y, z);
}

void Print(int x, double y, const char* z)
{
    cout << x << ' ';
    Print(y, z);
}

void Print(double y, const char* z)
{
    cout << y << ' ';
    Print(z);
}

void Print(const char* z)
{
    cout << z << ' ';
    Print();
}
*/
// int main()
// {
//     // func();              // 输出 0
//     // func(1);             // 输出 1
//     // func(1, 'a');        // 输出 2
//     func(1, 3.14, "xxx");// 输出 3
//     return 0;
// }


// #include<iostream>
// // #include<list>
// #include<cstring>
// using namespace std;
// #include"string_vector.h"

// int main()
// {
//     Wang::list<Wang::string> ls;
//     Wang::string s(10, 'a');
//     ls.emplace_back(s);    // 尾插，相当于v.push_back(string(10, 'a'));

//     ls.emplace_back(move(s));    // 尾插，相当于v.push_back(string(10, 'a'));

//     ls.emplace_back(5, 'x');    // 5个'x'构造

//     cout << endl;
//     ls.print();
//     // template <class InputIterator>
//     //     string  (InputIterator first, InputIterator last);
//     // char s[] = "abcdefg";
//     // ls.emplace_back(s, s + 5);    // 迭代器区间构造

//     return 0;
// }

#if 0

/***************** lambda表达式 ***************/

#include<iostream>
#include<algorithm>
using namespace std;

struct my_cmp
{
    bool operator()(int a, int b) const
    {
        return abs(a) < abs(b);
    }
};
void test01()
{
    int a[10] = { 4,-2,5,-6,1,-8,0,7,-10,3 };
    // sort(a, a + 10, my_cmp());
    sort(a, a + 10, [](int a, int b) { return abs(a) < abs(b); });
    for(auto e : a) cout << e << ' ';

    // auto add = [](int a, int b) -> int
    // {
    //     return a + b;
    // };

    // cout << add(1, 2) << endl;
}

void test02()
{
    int a = 10, b = 2;
    // auto func = []()
    // {
    //     cout << a << ' ' << b;  // err，无法访问外部变量
    //     // lambda函数体只能用lambda局部域和捕捉列表的对象
    // };

    // 捕捉a、b
    auto func = [&a, &b]()
    {
        cout << a << ' ' << b << endl; // 可以访问
        a = 1;  // err a不可修改
        b = 10; // err b不可修改
    };
    func();
    cout << a << ' ' << b;
}

/***
 * [var]  值捕捉
 * [&var] 引用捕捉
 * [=]    全部都用值捕捉
 * [&]    全部都用引用捕捉
 * [&, var] 除了var用值捕捉，其他的都用引用捕捉
 */

 int Add(int a, int b)
 {
    return a + b;
 }
 struct Functor
 {
    int operator()(int a, int b) const
    {
        return a + b;
    }
 };

 class A
 {
public:
    static int Add(int a, int b)
    {
        return a + b;
    }

    double add(double a, double b)
    {
        return a + b;
    }
 };
#include<functional>
/*
template <class Ret, class... Args> 
class function<Ret(Args...)>;
Ret: 返回值类型
Args: 参数列表

function用于包装函数
*/
void test03()
{
    function<int(int ,int)> f1 = Add;   // 注意返回值、参数列表要匹配
    function<int(int ,int)> f2 = Functor();
    function<int(int ,int)> f3 = [](int a, int b) { return a + b; };
    cout << f1(1, 2) << endl;
    cout << f2(1, 2) << endl;
    cout << f3(1, 2) << endl;

    function<int(int ,int)> f4 = &A::Add;
    cout << f4(1, 2) << endl;

    // 包装成员函数. 有隐含的this
    function<double(A*, double, double)> f5 = &A::add;  // 取成员函数的地址要加&
    A a;
    cout << f5(&a, 1.1, 2.2) << endl;

    // 这里也可以不用指针
    function<double(A, double, double)> f6 = &A::add;  // 取成员函数的地址要加&
    cout << f6(A(), 1.1, 2.2) << endl;
}


using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
    return a - b;
}

void test04()
{
    // 1. bind用于调整参数顺序（不常用）
    auto Sub_b1 = bind(Sub, _1, _2);
    cout << Sub_b1(10, 1) << endl;
    // _1 代表绑定后的函数的第一个实参
    // _2 代表绑定后的函数的第二个实参
    // ... 
    auto Sub_b2 = bind(Sub, _2, _1);
    cout << Sub_b2(10, 1) << endl;

    // 2. bind用于调整参数个数（常用）
    auto Sub_b3 = bind(Sub, 100, _1);   // Sub的第一个参数固定为100
    cout << Sub_b3(10) << endl; // Sub(100, 10)

    function<double(double, double)> f = bind(&A::add, A(), _1, _2);
    cout << f(1.1, 2.3) << endl;
}

int main()
{
    test04();
    return 0;
}


struct Pos
{
    int x;
    int y;
};


void test01()
{
    // int a[] = { 1,2,3,4 };
    // Pos p = { 2,4 };
    // // auto t = p;
    // int* arr = new int[10]{1,2,3};

    // int a = {1};
    // double b = {3.14};
    // char c = {'x'};

    // 而且赋值符号可以省略
}
class Date
{
    int _y, _m, _d;
public:
    Date(int y, int m, int d)
        :_y(y)
        ,_m(m)
        ,_d(d)
    {
        cout << "Date(int y, int m, int d)" << endl;
    }
    Date(initializer_list<int> il)
    {
        cout << "Date(initializer_list<int> il)" << endl;
    }
};
void test02()
{
    Date d1(2025, 11, 27);  // 构造
    Date d2{2025, 11, 28};  // 列表初始化。
    Date d3 = {2025, 11, 29};  // 拷贝列表初始化。
}



// #include<vector>
// #include<list>
// #include<map>
// #include<set>

// void test03()
// {
//     // auto il = { 1,2,3,4,5 };
//     // int a[5] = { 1,2,3,4,5 };
//     // vector<int> v1({ 1,2,3,4,5 });  // 调用vector的initializer_list的构造函数
//     // vector<int> v2{ 1,2,3,4,5 };    // 直接列表初始化。调用vector的initializer_list的构造函数
//     // vector<int> v3 = { 1,2,3,4,5 }; // 拷贝列表初始化。先调用vector的initializer_list的构造函数去构造一个临时对象，然后再拷贝给v3
//     // // 这三种初始化方式在功能上是等效的。推荐使用直接列表初始化

//     // vector<int> v1 { 1,2,3,4,5 };
//     // v1 = {1,2,3};   // initializer_list版本的赋值重载

//     list<char> ls { 'a','b','c' };      // initializer_list<char>
//     map<string, string> dict { {"left", "左"}, {"right", "右"} }; // initializer_list<pair<string,string>>
//     set<double> st { 1.1, 2.2, 3.3 };   // initializer_list<double>

//     initializer_list<pair<string,string>> il = { {"left", "左"}, {"right", "右"} };
// }

struct Node
{
    int val;
    Node* next;
    Node(int v)
        :val(v)
    {}
};

// void test05()
// {
//     // auto func = [](int v)
//     // {
//     //     if(v % 2 != 0)
//     //         return nullptr;
//     //     else
//     //         return new Node(v);
//     // };

// 	// // 可以推出返回值类型，可以省略 ->返回值类型
//     // auto add = [](int a, int b)
//     // {
//     //     return a + b;
//     // };
//     // cout << add(1, 2) << endl;  // 输出3
// }

// #include<algorithm>

struct my_cmp
{
    bool operator()(int a, int b) const
    {
        return abs(a) < abs(b);
    }
};
// void test06()
// {
//     int a[10] = { 4,-2,5,-6,1,-8,0,7,-10,3 };
//     sort(a, a + 10, my_cmp());
//     for(auto e : a) cout << e << ' ';
// }

// void test07()
// {
//     int a = 1, b = 20;
//     auto func = [&, b]()    // 函数体所用到的所变量都按引用捕捉，但是b按值捕捉
//     {
//         cout << a << ' ' << b << endl;
//         a++, b++;
//     };
//     func();   // 输出1 20
//     cout << a << ' ' << b << endl;  // 输出2 21
// }



#include<iostream>
#include <functional>
using namespace std;

int Add(int a, int b)   
{
    return a + b;
}
struct Functor
{
    int operator()(int a, int b) const
    {
        return a + b;
    }
};

void test08()
{
    function<int(int ,int)> f1 = Add;	    // 包装普通函数
    function<int(int ,int)> f2 = Functor(); // 包装仿函数
    function<int(int ,int)> f3 = [](int a, int b) { return a + b; };    // 包装lambda表达式
    cout << f1(1, 2) << endl;
    cout << f2(1, 2) << endl;
    cout << f3(1, 2) << endl;
}

class A
{
public:
    static int s_A_div(int a, int b)
    {
        cout << "static int s_A_div(int a, int b)" << endl;
        return a / b;
    }

    int A_div(int a, int b)
    {
        cout << "int A_div(int a, int b)" << endl;
        return a / b;
    }
};
#include<unordered_map>

// op为加减乘除运算符, 计算a op b 的结果
int cal(int a, int b, char op)
{
    static unordered_map<char, function<int(int, int)>> f = {
        {'+', [](int a, int b) { return a + b; }},
        {'-', [](int a, int b) { return a - b; }},
        {'*', [](int a, int b) { return a * b; }},
        {'/', [](int a, int b) { return a / b; }}
    };
    return f[op](a, b);
    // int res;
    // switch (op)
    // {
    // case '+':
    //     res = a + b;
    //     break;
    // case '-':
    //     res = a - b;
    //     break;
    // case '*':
    //     res = a * b;
    //     break;
    // case '/':
    //     res = a / b;
    //     break;
    // }
    // return res;
}

void test09()
{
    cout << cal(1, 2, '+') << endl;
    cout << cal(1, 2, '-') << endl;
    cout << cal(1, 2, '*') << endl;
    cout << cal(1, 2, '/') << endl;

    // // 1.包装静态成员函数
    // function<int(int,int)> f1 = &A::s_A_div;
    // cout << f1(4, 2) << endl;

    // // 2.包装非静态成员函数
    // function<int(A*, int, int)> f2 = &A::A_div; // 成员函数第一个参数是隐含的this
    // A a;
    // cout << f2(&a, 4, 2) << endl;

    // // 但是也可以这样写:
    // function<int(A, int, int)> f3 = &A::A_div; 
    // cout << f3(A(), 4, 2) << endl;
}
// auto newFunc = bind(func, arg_list);


#endif

#include<iostream>
#include<functional>
using namespace std;
using namespace std::placeholders;

void func(int a, int b, int c)
{
    cout << a << ' ' << b << ' ' << c << endl;
}

void test10()
{
    auto f1 = bind(func, 99, 98, 97);   // 把func函数的参数分别固定为99, 98, 97
    f1();   // 输出: 99 98 97

    // _1、_2等变量在placeholders命名空间里
    auto f2 = bind(func, 99, _1, _2);   // 把func函数的第1个参数固定为99, func的第2、3个参数分别为f2的第1、2个参数
    f2(10, 20);     // 输出: 99 10 20

    auto f3 = bind(func, _1, 99, _2);   // 把func函数的第2个参数固定为99, func的第1、3个参数分别为f2的第1、2个参数
    f3(10, 20);     // 输出: 10 99 20
}

int main()
{
    test10();
    return 0;
}